package com.stack.knowyouweb.controller;

import com.google.gson.Gson;

import com.stack.knowyoubase.constant.GlobalConst;
import com.stack.knowyoubean.bean.RepJson;
import com.stack.knowyoubean.bean.Schedule;
import com.stack.knowyouservice.service.ScheduleService;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Collection;
import java.util.List;

/**
 * 课程表响应接口
 * 不涉及共享资源，bean设为单例，减少内存和cpu浪费，线程安全
 * 前后端分离采用RestController或responseBody
 *
 * @author stack
 */
@RestController
@Scope("singleton")
@RequestMapping("/api")
public class CourseController {

    /**
     * 基于接口增强采用proxy代理方式
     */
    @Resource
    private ScheduleService scheduleService;

    @Resource
    private Gson gson;


    /**
     * 通过注入authentication,spring security中的用户信息获取参数，减少前端注入风险
     * 根据经过认证的角色响应课程表内容,不受前端传入数据影响
     * 学生可以看见全部课程
     * 教师只能看见开设的课程
     *
     * @param authentication 权限信息
     * @return 课程信息
     */
    @GetMapping("/course")
    public String courseInfo(Authentication authentication) {
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        List<Schedule> courses = null;
        for (GrantedAuthority authority : authorities) {
            if ("ROLE_teacher".equals(authority.getAuthority())) {
                courses = scheduleService.courseInfo(authentication.getName());
            }
        }
        //学生可以看见的课程信息
        if (courses == null) {
            courses = scheduleService.courseInfo(null);
        }
        RepJson<List<Schedule>> repJson = new RepJson<>();
        repJson.setCode(GlobalConst.SUCCESS_CODE);
        //解决没有课程添加时的错位问题
        if (courses.size() == 0) {
            repJson.setCount(courses.size() + 1);
        } else {
            repJson.setCount(courses.size());
        }

        repJson.setData(courses);
        return gson.toJson(repJson);
    }

    /**
     * 安全问题：认证的教师，可以注入不属于它的课程 服务层处理判断是否持有改课程
     *
     * @param schedule 权限信息
     * @return 添加成功标记
     */

    @PostMapping("/course")
    public String courseInsert(Schedule schedule, Authentication authentication) {
        RepJson<String> repJson = new RepJson<>();
        if (scheduleService.courseInsert(schedule, authentication)) {
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("添加课程成功");
            repJson.setData(GlobalConst.SUCCESS_TYPE);
            return gson.toJson(repJson);
        } else {
            repJson.setCode(GlobalConst.ERROR_CODE);
            repJson.setMsg("添加课程失败");
            repJson.setData(GlobalConst.ERROR_TYPE);
            return gson.toJson(repJson);
        }
    }


    /**
     * 安全问题：认证的教师，可以注入更新/删除不属于它的课程 服务层处理是否持有改课程
     *
     * @param schedule 权限信息
     * @return 更新标记
     */

    @PutMapping("/course")
    public String courseUpdate(Schedule schedule, Authentication authentication) {
        RepJson<String> repJson = new RepJson<>();
        if (scheduleService.courseUpdate(schedule, authentication)) {
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("更新课程成功");
            repJson.setData(GlobalConst.SUCCESS_TYPE);
            return gson.toJson(repJson);
        } else {
            repJson.setCode(GlobalConst.ERROR_CODE);
            repJson.setMsg("更新课程失败");
            repJson.setData(GlobalConst.ERROR_TYPE);
            return gson.toJson(repJson);
        }
    }

    /**
     * 安全问题：认证的教师，可以注入更新/删除不属于它的课程 服务层处理是否持有改课程
     *
     * @param schedule 权限信息
     * @return 更新标记
     */
    @DeleteMapping("/course")
    public String courseDelete(Schedule schedule, Authentication authentication) {
        RepJson<String> repJson = new RepJson<>();
        if (scheduleService.courseDelete(schedule, authentication)) {
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("删除课程成功");
            repJson.setData(GlobalConst.SUCCESS_TYPE);
            return gson.toJson(repJson);
        } else {
            repJson.setCode(GlobalConst.ERROR_CODE);
            repJson.setMsg("删除课程失败");
            repJson.setData(GlobalConst.ERROR_TYPE);
            return gson.toJson(repJson);
        }
    }

    /**
     * 选择课程信息，保存在服务端,以服务端为主
     * 防止课程端注入
     *
     * @param courseid 课程号
     * @param session  session域
     * @return 选择成功的标记
     */
    @PostMapping("/course/chose")
    public String courseChose(Integer courseid, HttpSession session, Authentication authentication) {
        RepJson<String> repJson = new RepJson<>();
        if (courseid == null) {
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("选择课程失败");
            repJson.setData(GlobalConst.ERROR_TYPE);
            return gson.toJson(repJson);
        }
        boolean b = scheduleService.courseChose(courseid, authentication);
        if (!b) {
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("选择课程失败,你没有这门课程");
            repJson.setData(GlobalConst.ERROR_TYPE);
            return gson.toJson(repJson);
        }
        try {
            session.setAttribute("courseid", courseid);
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("选择课程成功");
            repJson.setData(GlobalConst.SUCCESS_TYPE);
        } catch (Exception e) {
            repJson.setCode(GlobalConst.SUCCESS_CODE);
            repJson.setMsg("选择课程失败");
            repJson.setData(GlobalConst.ERROR_TYPE);
        }

        return gson.toJson(repJson);
    }

}
